package failover

import (
	"context"
	"errors"
	"log"
	"sync/atomic"
	"webook/internal/service/sms"
)

type FailOverSMSService struct {
	svcs []sms.Service
	//v1的字段
	idx uint64
}

func NewFailOverSMSService(svcs []sms.Service) *FailOverSMSService {
	return &FailOverSMSService{
		svcs: svcs,
	}
}

func (f *FailOverSMSService) Send(ctx context.Context, tplId string, args []string, numbers ...string) error {
	for _, svc := range f.svcs { //负载不均衡 一般第一个就成功
		err := svc.Send(ctx, tplId, args, numbers...)
		if err == nil {
			log.Println("发送成功")
			return nil
		}
		log.Println(err)
	}
	return errors.New("轮询了所有服务商，但是发送都失败了") //一般说明是自身网络问题
}

// SendV1 起始下标轮询 出错也轮询
func (f *FailOverSMSService) SendV1(ctx context.Context, tplId string, args []string, numbers ...string) error {
	idx := atomic.AddUint64(&f.idx, 1) //保证线程安全
	length := uint64(len(f.svcs))
	for i := idx; i < idx+length; i++ {
		svc := f.svcs[i%length]
		err := svc.Send(ctx, tplId, args, numbers...)
		switch {
		case err == nil:
			return nil
		case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
			//前者是被取消 后者是超时
			return err
		}
		log.Println(err)
	}
	return errors.New("轮询了所有服务商，但是发送都失败了") //一般说明是自身网络问题
}
